<template>
  <el-drawer v-model="dialogVisible" :title="title" size="50%" @close="close">
    <el-form ref="ruleFormRef" :model="ruleForm" :rules="rules" label-width="100px">
      <el-form-item label="角色名称" prop="name" v-if="!menuShow">
        <el-input v-model="ruleForm.name" placeholder="请输入角色名称" />
      </el-form-item>
      <el-form-item label="角色标识" prop="code" v-if="!menuShow">
        <el-input v-model="ruleForm.code" placeholder="请输入角色标识" />
      </el-form-item>
      <el-form-item label="角色状态" v-if="!menuShow">
        <el-switch
          v-model="ruleForm.status"
          :active-value="1"
          :inactive-value="0"
          inline-prompt
          active-text="启用"
          inactive-text="禁用"
        />
      </el-form-item>
      <el-form-item label="显示排序" prop="sort" v-if="!menuShow">
        <el-input-number v-model="ruleForm.sort" :min="0" :max="999" controls-position="right" />
      </el-form-item>
      <el-form-item label="角色描述" v-if="!menuShow">
        <el-input
          v-model="ruleForm.describe"
          type="textarea"
          placeholder="请输入角色描述"
          maxlength="200"
          show-word-limit
          :rows="4"
        />
      </el-form-item>
      <el-form-item label="菜单权限" v-if="menuShow">
        <el-tree
          ref="menuTreeRef"
          :data="menuOptions"
          show-checkbox
          node-key="id"
          :props="defaultProps"
          empty-text="加载中，请稍候"
          :default-checked-keys="checkedMenuIds"
          :check-strictly="false"
        />
      </el-form-item>
    </el-form>
    <template #footer>
      <span class="dialog-footer">
        <el-button @click="dialogVisible = false">取消</el-button>
        <el-button type="primary" @click="handleSubmit" :loading="submitLoading">确定</el-button>
      </span>
    </template>
  </el-drawer>
</template>

<script lang="ts" setup>
import { reactive, ref, onMounted } from 'vue'
import { FormInstance, ElMessage, ElTree } from 'element-plus'
import { listMenu } from '@/api/menus'
import { addRole, updateRole, roleMenus, roleMenuIds } from '@/api/roles'

const emit = defineEmits(['success'])

// 表单ref
const ruleFormRef = ref<FormInstance>()
// 树形ref
const menuTreeRef = ref<InstanceType<typeof ElTree>>()
// 显示状态
const dialogVisible = ref(false)
// 授权菜单状态
const menuShow = ref(false)
// 标题
const title = ref('新增角色')
// 提交状态
const submitLoading = ref(false)
// 菜单选项数据
const menuOptions = ref([])
// 选中的菜单IDs
const checkedMenuIds = ref<number[]>([])

// 表单数据
const ruleForm = reactive({
  id: undefined,
  name: '',
  code: '',
  sort: 0,
  describe: '',
  status: '0',
})

// 添加展开的节点ID数组
const expandedKeys = ref<number[]>([])

// 处理菜单数据，获取所有叶子节点
const getLeafKeys = (data: any[]): number[] => {
  const leafKeys: number[] = []
  const traverse = (nodes: any[]) => {
    nodes.forEach(node => {
      if (!node.children || node.children.length === 0) {
        leafKeys.push(node.id)
      } else {
        traverse(node.children)
      }
    })
  }
  traverse(data)
  return leafKeys
}

// 过滤出真正需要选中的节点
const filterCheckedKeys = (allCheckedKeys: number[], menuData: any[]): number[] => {
  const leafKeys = getLeafKeys(menuData)
  return allCheckedKeys.filter(key => leafKeys.includes(key))
}
// 表单校验规则
const rules = reactive({
  name: [
    { required: true, message: '请输入角色名称', trigger: 'blur' },
    { min: 2, max: 20, message: '长度在 2 到 20 个字符', trigger: 'blur' }
  ],
  code: [
    { required: true, message: '请输入角色标识', trigger: 'blur' },
    { pattern: /^[a-zA-Z_][a-zA-Z0-9_]*$/, message: '只能包含字母、数字和下划线，且必须以字母或下划线开头', trigger: 'blur' }
  ],
})

// 树形配置
const defaultProps = {
  children: 'children',
  label: 'name',
}

/** 获取菜单列表 */
const getMenuList = async () => {
  try {
    const res = await listMenu()
    menuOptions.value = res.data
  } catch (error: any) {
    ElMessage.error(error.msg || '获取菜单列表失败')
  }
}

/** 表单重置 */
const reset = () => {
  submitLoading.value = false
  ruleFormRef.value?.resetFields()
  checkedMenuIds.value = []
  Object.assign(ruleForm, {
    id: undefined,
    name: '',
    code: '',
    sort:0,
    describe: '',
    status: '0',
  })
}

/** 关闭弹窗 */
const close = () => {
  reset()
}

/** 显示弹窗 */
const show = async (row?: any, showMenu?: boolean) => {
  menuShow.value = showMenu || false

  reset()
  await getMenuList()
  // 获取已授权的菜单
  if (row?.id) {
    if(showMenu) {
      title.value = '授权菜单'
    }else{
      title.value = '修改角色'
    }
    Object.assign(ruleForm, {
      id: row.id,
      name: row.name,
      code: row.code,
      sort: row.sort,
      describe: row.describe,
      status: row.status
    })
    // 设置已选中的菜单
    // const menuIds = await roleMenuIds(row.id)
    // checkedMenuIds.value = menuIds.data || []
    const menuIds = await roleMenuIds(row.id)
    // 只选中叶子节点
    checkedMenuIds.value = filterCheckedKeys(menuIds.data || [], menuOptions.value)
    // 展开所有父节点
    expandedKeys.value = menuIds.data || []
  } else {
    title.value = '新增角色'
  }

  dialogVisible.value = true
}

/** 提交表单 */
const handleSubmit = async () => {
  if (!ruleFormRef.value) return

  await ruleFormRef.value.validate(async (valid, fields) => {
    if (valid) {
      submitLoading.value = true
      try {
        // 获取表单数据
        const formData = {
          name: ruleForm.name,
          code: ruleForm.code,
          sort: ruleForm.sort,
          describe: ruleForm.describe,
          status: ruleForm.status
        }

        // 如果是编辑，添加id
        if (ruleForm.id) {
          formData.id = ruleForm.id
        }

        // 打印发送的数据
        console.log('提交的数据:', formData)

        if (ruleForm.id) {
          if (menuShow.value) {
            // 获取菜单相关数据
            // const menuIds = menuTreeRef.value?.getCheckedKeys(false) as number[]
            // const halfCheckedIds = menuTreeRef.value?.getHalfCheckedKeys() as number[]
            // const allCheckedIds = [...menuIds, ...halfCheckedIds]

            // 处理菜单授权
            // const authRes = await roleMenus(ruleForm.id, allCheckedIds)
            // 获取所有选中和半选的节点
            const menuIds = menuTreeRef.value?.getCheckedKeys(false) as number[]
            const halfCheckedIds = menuTreeRef.value?.getHalfCheckedKeys() as number[]
            const allCheckedIds = [...menuIds, ...halfCheckedIds]

            const authRes = await roleMenus(ruleForm.id, allCheckedIds)
            console.log('授权结果:', authRes)
            ElMessage.success('授权成功')
          } else {
            // 修改角色
            const updateRes = await updateRole(formData)
            console.log('修改结果:', updateRes)
            ElMessage.success('修改成功')
          }
        } else {
          // 新增角色
          const addRes = await addRole(formData)
          console.log('新增结果:', addRes)
          ElMessage.success('新增成功')
        }

        dialogVisible.value = false
        emit('success')
      } catch (error: any) {
        console.error('操作失败:', error)
        ElMessage.error(error?.msg || '操作失败')
      } finally {
        submitLoading.value = false
      }
    } else {
      console.error('表单验证失败:', fields)
    }
  })
}
defineExpose({
  show,
})
</script>

<style scoped>
.dialog-footer {
  padding: 20px 0;
}

:deep(.el-drawer__body) {
  padding: 20px;
}

:deep(.el-form-item:last-child) {
  margin-bottom: 0;
}
</style>